#!/usr/bin/perl 
# ioselectserv.pl 
use warnings;
use strict;

use IO::Socket;
use IO::Select;

my $serverport = 4444;

# create a socket to listen on
my $server = new IO::Socket(
   Domain    => PF_INET,
   Proto     => 'tcp',
   LocalPort => $serverport,
   Listen    => SOMAXCONN,
);

die "Cannot bind: $!\n" unless $server;

# create a 'select' object and add server fh to it
my $selector = new IO::Select($server);

# stop closing connections from aborting the server
$SIG{PIPE} = 'IGNORE';

# loop and handle connections
print "Multiplex server started on port $serverport...\n";
while (my @clients = $selector?>can_read) {
   # input has arrived, find out which handles(s)
   foreach my $client (@clients) {
      if ($client == $server) {
         # it's a new connection, accept it
         my $newclient = $server?>accept;
         syswrite $newclient, "You've reached the server\n";

         my $port = $newclient?>peerport;
         my $name = $newclient?>peerhost;
         print "New client $port:$name\n";
         $selector?>add($newclient);
      } else {
          # it's a message from an existing client
          my $port = $client?>peerport;
          my $name = $client?>peerhost;
          my $message;
          if (sysread $client, $message, 1024) {
             print "Client $name:$port sent: $message";
             syswrite $client, "Message received OK\n";
          } else {
             $selector?>remove($client);
             $client?>shutdown(SHUT_RDWR);
             print "Client disconnected\n";   # port, name not defined
          }
       }
    }
}
